SPDX-FileCopyrightText: 2019 Adrien Dumont & Johan Metzger SPDX-FileCopyrightText: 2024 AlICe laboratory https://alicelab.be
SPDX-License-Identifier: GPL-3.0-or-later
import bpy
import math
import randomPrérequis : Nécessite d’être en mode object Calque vierge Interface en français
createplane = bpy.ops.mesh.primitive_plane_add
selectall = bpy.ops.object.select_all
extrude = bpy.ops.mesh.extrude_region_move
delete = bpy.ops.object.delete
modeset = bpy.ops.object.mode_setdef cleanscene():
selectall(action="SELECT")
delete(use_global=False)def selectionne(a):
objectToSelect = bpy.data.objects[a]
objectToSelect.select_set(True)
bpy.context.view_layer.objects.active = objectToSelectdef intersect():
bpy.ops.object.modifier_add(type="BOOLEAN")
bpy.context.object.modifiers["Booléen"].operation = "INTERSECT"
bpy.context.object.modifiers["Booléen"].object = bpy.data.objects["CubeEnglobant"]
bpy.ops.object.modifier_apply(apply_as="DATA", modifier="Booléen")def wireframe():
bpy.ops.object.modifier_add(type="WIREFRAME")
bpy.context.object.modifiers["Fil de fer"].thickness = WidthWiredef curseur(x, y, z):
bpy.context.scene.cursor.location[0] = x
bpy.context.scene.cursor.location[1] = y
bpy.context.scene.cursor.location[2] = zdef get_override(area_type, region_type):
for area in bpy.context.screen.areas:
if area.type == area_type:
for region in area.regions:
if region.type == region_type:
override = {"area": area, "region": region}
return override
raise RuntimeError(
"Wasn't able to find",
region_type,
" in area ",
area_type,
"\n Make sure it's open while executing script.",
)Réinitialise les compteurs des boucles de création des petits cubes Assigne : - des valeurs au coordonnées des carrés (OX,OX,OZ) - les longueurs d’extrusion des carrés pour en faire des pavés
def makevar(NbCubesParAxe, DimCube):Compteurs en X,Z
CX = 0
CZ = 0Origine du plan
OX = DimCube / 2
OXinit = OX
OY = 0
OYinit = OY
OZ = DimCube / 2
OZinit = OZDistances d’extrusion
Ex = (DimCube * NbCubesParAxe) / 2 - DimCube / 2
Exinit = Ex
Ey = ((NbCubesParAxe - 1) * DimCube) / 2 # (NbCubesParAxe*DimCube)/2
Ez = ((NbCubesParAxe - 1) * DimCube) / 2
return CX, CZ, OX, OXinit, OY, OYinit, OZ, OZinit, Ex, Exinit, Ey, EzNbCubesParAxe = 3 # Nombre de cubes par axe
ARmaxD = 90 # Angle de rotation maximale
ARstep = ARmaxD / NbCubesParAxe # Incrément de l'angle de rotation
DimCube = 1 # Largeur d'un cube
WidthWire = DimCube / 8 # Largeur du wireframe
EntraxeCube = EC = DimCube # Espacement entre les cubes
SF = (NbCubesParAxe * EC) * 1.1 # Size du cube englobant
PF = (NbCubesParAxe * EC) / 2 # Position du cube englobant
x = y = z = (DimCube * NbCubesParAxe) / 2 # Position du curseur au centre du cube finalNettoyage du modèle
cleanscene()Initialisation des variables
CX, CZ, OX, OXinit, OY, OYinit, OZ, OZinit, Ex, Exinit, Ey, Ez = makevar(
NbCubesParAxe, DimCube
)Initialise le nombre de faces du cube a créer
faces = 0Création des cubes
while faces < 6:
while CZ < NbCubesParAxe:
while CX < NbCubesParAxe:
if faces < 3: # Faces normales
ARmaxD = ARstep * CZ
print("inférieur à 3")
AxeRotaPlan = "Z" # O = Axe X
AngleRotaFace = 1.5708
elif faces < 4: # Face normal mais rotation 180°
ARmaxD = ARstep * CZ
print("inférieur à 5")
AxeRotaPlan = "X" # O = Axe X
AngleRotaFace = 1.5708
elif faces < 5: # Face déformée (dessus)
ARmaxD = 90
print("inférieur à 6")
AxeRotaPlan = "X" # O = Axe X
AngleRotaFace = 3.14159
elif faces < 6: # Face régulière (dessous)
ARmaxD = 0
print("inférieur à 6")
AxeRotaPlan = "X" # O = Axe X
AngleRotaFace = 1.5708Fin du conditionnel
createplane(size=DimCube, location=(OX, OY, OZ)) # Crée le plan
bpy.context.object.rotation_euler[0] = 1.5708 # Verticalise le plan
bpy.ops.transform.rotate(
value=math.radians(random.randint(-ARmaxD, ARmaxD)),
orient_axis="Y",
orient_type="VIEW",
orient_matrix=((-1, 0, -0), (0, -1, 0), (-0, 0, -1)),
orient_matrix_type="VIEW",
mirror=True,
use_proportional_edit=False,
proportional_edit_falloff="SMOOTH",
proportional_size=1,
use_proportional_connected=False,
use_proportional_projected=False,
)
modeset(mode="EDIT")
extrude(
MESH_OT_extrude_region={},
TRANSFORM_OT_translate={"value": (Ex, Ey, Ez)},
)
modeset(mode="OBJECT")
wireframe()
intersect()
selectall(action="DESELECT")
OX = OX + EC
CX = CX + 1
Ex = Ex - DimCube
OX = OXinit
OZ = OZ + 1
Ex = Exinit
Ez = Ez - DimCube
CX = 0
CZ = CZ + 1
curseur(x, y, z) # Positionnement du curseur au centre du cube
selectall(action="SELECT")
bpy.context.scene.tool_settings.transform_pivot_point = "CURSOR"
override = get_override("VIEW_3D", "WINDOW") # Remplacement du contexte
bpy.ops.transform.rotate(
override,
value=AngleRotaFace,
orient_axis=AxeRotaPlan,
orient_type="GLOBAL",
orient_matrix=((1, 0, 0), (0, 1, 0), (0, 0, 1)),
orient_matrix_type="GLOBAL",
constraint_axis=(False, False, True),
mirror=True,
use_proportional_edit=True,
proportional_edit_falloff="SMOOTH",
proportional_size=1000,
use_proportional_connected=False,
use_proportional_projected=False,
)
faces = faces + 1
CX, CZ, OX, OXinit, OY, OYinit, OZ, OZinit, Ex, Exinit, Ey, Ez = makevar(
NbCubesParAxe, DimCube
)
modeset(mode="OBJECT") # Passage en mode object
selectall(action="DESELECT") # Deselectionne tout